﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
namespace Athena.Performance.Test
{
    using ProxyGenerator;
    using ProxyInterfaces;
    using ProxyInterfaces.Arguments;
    using Transport.BeetleX;
    using Transport.DotNetty;
    class Program
    {

        private static IServiceProvider BuildServiceCollection(Action<IServiceCollection> action)
        {
            var serviceCollection = new ServiceCollection();
            serviceCollection.AddLogging();
            action?.Invoke(serviceCollection);
            return serviceCollection.BuildServiceProvider();
        }

        static void Main(string[] args)
        {
            Console.WriteLine("开始..版本1.0.0.1的测试");
            var selectId = 0;
            while (selectId != 1 && selectId != 2)
            {
                Console.WriteLine("请选择传输模式:");
                Console.WriteLine("1:DotNetty");
                Console.WriteLine("2:BeetleX");
                int.TryParse(Console.ReadLine(), out selectId);
            }

            var serviceProvider = BuildServiceCollection((serviceCollection) =>
            {
                serviceCollection.AddAthenaCore(new ServiceDescriptor()
                {
                    Id = "athena.xunit.test",
                    Name = "雅典娜RPC-Test"
                });
                serviceCollection.AddServiceRuntimeCore();
                serviceCollection.AddRouteCore();
                serviceCollection.AddFileRouteManager();
                if (selectId == 1)
                {
                    serviceCollection.AddDotNettyTransport();
                }
                else
                {
                    serviceCollection.AddBeetleXTransport();
                }
                serviceCollection.AddSingleton<IUser, User>();
            });
            serviceProvider.UseService();


            var clientProvider = BuildServiceCollection((serviceCollection) =>
            {
                serviceCollection.AddAthenaCore(new ServiceDescriptor()
                {
                    Id = "athena.xunit.client.test",
                    Name = "雅典娜RPC-client-Test"
                });
                serviceCollection.AddDefaultClientRuntime();
                serviceCollection.AddAthenaProxy();

                if (selectId == 1)
                {
                    serviceCollection.AddDotNettyTransport();
                }
                else
                {
                    serviceCollection.AddBeetleXTransport();
                }
            });

            //while (true)
            //{
            //    RunMultiple(clientProvider);
            //    Console.WriteLine("压测结束 y:继续 其他键:退出");

            //    if (Console.ReadLine().ToUpper() != "Y")
            //    {
            //        break;
            //    }
            //}
            Console.ReadKey();
        }

        static async void RunSingleThread(IServiceProvider serviceProvider)
        {
            var serviceProxyFactory = serviceProvider.GetRequiredService<IServiceProxyFactory>();
            var stopWatch = new Stopwatch();
            var user = serviceProxyFactory.CreateProxy<IUser>();
            var resultUserLogin = user.Login(new ArguUserLogin()
            {
                UserName = "Danny",
                Password = "123"
            }).GetAwaiter().GetResult();

            if (!string.IsNullOrWhiteSpace(resultUserLogin.Token))
            {
                Console.WriteLine("预热成功,开始压力测试");
                stopWatch.Start();
                int success = 0;
                for (var i = 0; i < 1000; i++)
                {
                    var result = user.Login(new ArguUserLogin()
                    {
                        UserName = "Danny",
                        Password = "123"
                    }).GetAwaiter().GetResult();
                    if (!string.IsNullOrWhiteSpace(resultUserLogin.Token))
                    {
                        success++;
                    }
                }
                stopWatch.Stop();
                Console.WriteLine($"1000次压测结束,成功：{success},失败：{1000 - success},耗时：{stopWatch.ElapsedMilliseconds} ms");


                //stopWatch.Reset();
                //stopWatch.Start();
                //success = 0;
                //for (var i = 0; i < 10000; i++)
                //{
                //    var result = user.Login(new ArguUserLogin()
                //    {
                //        UserName = "Danny",
                //        Password = "123"
                //    }).GetAwaiter().GetResult();
                //    if (!string.IsNullOrWhiteSpace(resultUserLogin.Token))
                //    {
                //        success++;
                //    }
                //}
                //stopWatch.Stop();
                //Console.WriteLine($"10000次压测结束,成功：{success},失败：{10000 - success},耗时：{stopWatch.ElapsedMilliseconds} ms");

                //stopWatch.Reset();
                //stopWatch.Start();
                //success = 0;
                //for (var i = 0; i < 10000; i++)
                //{
                //    var result = user.Login(new ArguUserLogin()
                //    {
                //        UserName = "Danny",
                //        Password = "123"
                //    }).GetAwaiter().GetResult();
                //    if (!string.IsNullOrWhiteSpace(resultUserLogin.Token))
                //    {
                //        success++;
                //    }
                //}
                //stopWatch.Stop();
                //Console.WriteLine($"10000次压测结束,成功：{success},失败：{100000 - success},耗时：{stopWatch.ElapsedMilliseconds} ms");
            }
            else
            {
                Console.WriteLine("预热失败");
            }
        }

        static async void RunMultiple(IServiceProvider serviceProvider)
        {
            var serviceProxyFactory = serviceProvider.GetRequiredService<IServiceProxyFactory>();



            var user = serviceProxyFactory.CreateProxy<IUser>();
            await user.Login(new ArguUserLogin()
            {
                UserName = "Danny",
                Password = "123"
            });
            Console.WriteLine("预热完成");
            var stopwatch = new Stopwatch();
            stopwatch.Start();
            var tasks = new List<Task>();

            for (var i = 0; i < 1000; i++)
            {
                var item = Task.Run(async () =>
                {
                    for (int k = 0; k < 1000; k++)
                    {
                        user = serviceProxyFactory.CreateProxy<IUser>();
                        var result = await user.Login(new ArguUserLogin()
                        {
                            UserName = "Danny",
                            Password = "123"
                        });
                        //Console.WriteLine("tst");
                    }
                });
                tasks.Add(item);
            }

            Task.WaitAll(tasks.ToArray());
            stopwatch.Stop();
            Console.WriteLine($"10000次压测结束  平均:{stopwatch.Elapsed.TotalMilliseconds / (1000 * 100)} ms");
        }
    }
}
